import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { Form, Input, Button, message, Modal, Table, Checkbox, Select } from 'antd';
import './style.scss';
import { useForm } from 'antd/lib/form/Form';

import { useLocation } from 'react-router-dom';
import { clearNull } from 'utils/tools';
import qs from 'query-string';
import { NewWordInfo, WordGroupsInfo } from 'admin/schema/ExtendQuestion';
import {
  getNewWords,
  getWordGroups,
  postTraingrammar,
  saveNewWords,
  understandNewWords,
} from 'admin/servers/servers';
import { debounce } from 'lodash';
const { Option } = Select;
type Props = {
  /**
   * 组件入参配置
   */
  modelProp: {
    /**
     * 扩展问Id
     */
    extendQuestionId: number;
    /**
     * 扩展问题
     */
    extendQuestionName: string;
    /**
     * 来源：操作学习按钮进入弹窗，需要调用学习接口
     */
    modeType?: 'study';
  };
  /**
   * 操作回调
   */
  callBack: (fresh?: boolean) => void;
};

/**
 * 新词录入弹窗，语义学习弹窗
 * 示例：AI管理-机器人管理-版本管理-配置话术流程-问答库-扩展列表
 */
const NewWordsModel: React.FC<Props> = ({
  modelProp: { extendQuestionId, extendQuestionName, modeType },
  callBack,
}) => {
  const [form] = useForm();
  // 确定按钮loading
  const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
  const [noUnderstandWords, setNoUnderstandWords] = useState<string>('');
  // 存储新词
  const [newWords, setNewWords] = useState<NewWordInfo[]>([]);
  // 存储原子词
  const [atomicWords, setAtomicWords] = useState<string[]>([]);
  const [wordGroup, setWordGroup] = useState<WordGroupsInfo[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [tableLoading, setTableLoading] = useState(false);
  // 新词条组成的词组
  const [newWordGroup, setNewWordGroup] = useState<string[]>([]);
  // 弹窗显示隐藏
  const [visible, setVisible] = useState<boolean>(false);
  const [checkedRow, setCheckedRow] = useState<number>(-1);
  // 路由location
  const location = useLocation();
  // URL查询字符串=>对象
  const query = useMemo(() => {
    return qs.parse(location.search);
  }, [location.search]);

  /** 请求新词列表
   * 逻辑：
   * 查询新词是否存在
   * 获取新词列表
   * 查询原子词 */
  async function getNewWordsList(word: string) {
    visible && setTableLoading(true);
    try {
      const { data } = await getNewWords(
        clearNull({
          extendQuestionId,
          extendQuestionName: word,
        })
      );
      // 获取：新词、原子词
      const { newWords, atomicWords } = data;
      setAtomicWords(atomicWords);
      console.log('原子词*ooooo', atomicWords);
      if (!newWords) {
        // no
        // 不显示新词发现弹窗
        console.log('1>>>>>>>>>无新词****', newWords);
        // 没有新词 -> 调用语义文法接口
        await doTraingRammar(extendQuestionId, atomicWords);
      } else {
        // yes
        // 显示新词发现弹窗
        openModal();
        // 自动加入选择数组
        const selectRow: Array<number> = [];
        const groups: Array<string> = [];
        newWords.map((item: NewWordInfo, rowKey: number) => {
          item.key = rowKey;
          item.isChoosed = false;
          item.isRequired = false;
          item.isAddBusinessWord = false;
          // 同义词，默认选中
          if (item.wordType === '0') {
            item.isChoosed = true;
            selectRow.push(rowKey);
          }
          // 存储新词条作为词组
          groups.push(item.word as any);

          return item;
        });
        console.log('2>>>>>>>>>有新词----新词列表-初始化', newWords);
        const newGroups = [...new Set(groups)];
        console.log('新词词类去重后的列表', newGroups);
        console.log('默认选中的行', selectRow);
        setNewWords(newWords);
        form.resetFields();
        setSelectedRowKeys(selectRow);
        setNewWordGroup(newGroups);
      }
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
    visible && setTableLoading(false);
  }
  /**初始化词组 */
  const initWordGroups = useCallback(async () => {
    try {
      const versionId = Number(query.versionId);
      const res = await getWordGroups({ versionId });
      if (res.code === 0) {
        // 成功
        if (res.data) {
          setWordGroup(res.data);
        }
      } else {
        // 失败
        message.error(`${res.tips}(错误码: ${res.code})`);
      }
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
  }, [query.versionId]);

  /**
   * 表单赋值&初始化
   */
  useEffect(() => {
    console.log('新词弹窗组件-init');
    if (extendQuestionId) {
      // 请求发现新词接口
      getNewWordsList(extendQuestionName);
    }
    return () => {
      console.log('新词弹窗组件-unmount');
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [extendQuestionId, extendQuestionName]);

  useEffect(() => {
    if (visible && extendQuestionName) {
      // 初始化未理解词
      setNoUnderstandWords(extendQuestionName);
      // 初始化-请求词组接口
      initWordGroups();
    }
  }, [extendQuestionName, initWordGroups, visible]);
  /**
   * 新词弹窗-确认按钮
   */
  const submitForm = async () => {
    setConfirmLoading(true);
    // 取表单全部值
    const { lists } = form.getFieldsValue(true);
    console.log('**lists', lists);
    // 更新isChoosed字段
    if (!selectedRowKeys.length) {
      message.info('当前没有选中项');
      return;
    }
    // 选中的行，更新为true
    selectedRowKeys.map((rowKey: React.Key) => {
      lists[rowKey as number].isChoosed = true;
    });
    // 专业词重置为false
    lists.map((item: NewWordInfo, index: number) => {
      item.isAddBusinessWord = false;
    });
    // 专业词选中的行，更新为true
    if (checkedRow >= 0) {
      lists[checkedRow].isAddBusinessWord = true;
    }
    // 新建的词条，词类为undefined的时，需要剔除掉
    const lists_copy = JSON.parse(JSON.stringify(lists));
    const lists_new = lists_copy.filter((item: NewWordInfo, index: number) => {
      // 删除无用属性
      delete item.key;
      delete item.wordCategoryId;
      delete item.wordEntry;
      if (item.wordCategory !== undefined) {
        return item;
      }
    });
    console.log('弹窗确定--请求参数-newWords-1', lists);
    console.log('弹窗确定--请求参数-newWords-2', lists_copy);
    console.log('弹窗确定--请求参数-newWords-3', lists_new);
    // 方便测试
    // setConfirmLoading(false);
    // return;
    try {
      await saveNewWords({
        extendQuestionId,
        newWords: lists_new,
        atomicWords,
      });
      console.log('保存新词成功，继续语义文法接口');
      // 保存新词，调用语义文法接口
      await doTraingRammar(extendQuestionId, atomicWords);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
    setConfirmLoading(false);
  };
  /** 语义文法接口（如果是点学习进来，还需要调用学习接口）
   * 运用场景：
   * 1.发现新词 -> 保存新词-> 调用语义文法接口
   * 2.发现新词 -> 没有新词 -> 调用语义文法接口
   */
  const doTraingRammar = async (extendQuestionId: number, atomicWords: any) => {
    try {
      await postTraingrammar(
        clearNull({
          extendQuestionId,
          atomicWords,
        })
      );
      console.log('语义文法接口--成功', extendQuestionId, atomicWords);
      if (modeType === 'study') {
        // 操作学习来源，需要请求学习接口
        await understandNewWords(
          clearNull({
            extendQuestionId,
          })
        );
        console.log('学习接口--成功');
        message.success('新词学习成功');
      }
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
    // 关闭弹窗，刷新列表
    closeModal(true);
  };
  /**打开弹窗
   */
  const openModal = () => {
    setVisible(true);
  };
  /**关闭弹窗
   * type:是否需要刷新
   */
  const closeModal = (fresh?: boolean) => {
    if (visible) {
      form && form.resetFields();
      visible && setVisible(false);
    }
    callBack(fresh);
  };
  /**新建词条 */
  const handleAdd = () => {
    // todo-新增后，滚动到最后一行
    // 应该提取当前表单数据，更新newWords
    const { lists } = form.getFieldsValue(true);
    console.log(lists, '实时表单值');
    const newWords_copy = [...lists];
    newWords_copy.push({
      /**前端索引 */
      key: newWords_copy.length,
      /**新词条*/
      word: extendQuestionName,
      /** 类型 0 - 同义词（近类）, 1 - 词组（父类）*/
      wordType: '',
      /** 词类*/
      wordCategory: undefined,
      /** 别名*/
      wordEntrys: '',
      /** 必选*/
      isRequired: false,
      /** 自动生成专业词*/
      isAddBusinessWord: false,
      /** 是否选中 true, false*/
      isChoosed: false,
      /** 传新词发现时对应的返回传*/
      isGeneraled: false,
      /** 传新词发现时对应的返回传*/
      isAtomiced: false,
    });
    console.log(newWords_copy, '操作【新建】之后的表单值');
    setNewWords(newWords_copy);
    setTimeout(() => {
      form.resetFields();
    }, 0);
  };
  /**屏幕取词 */
  function getSelectText(words: string) {
    // Firefox, Safari, Opera下，可以用window.getSelection(), 参考MDC
    // IE下，可以用document.selection.createRange().text, 参考MSDN放在一起：
    // 注意：当选中的是input[type=text]里面的值时getSelection在Firefox和Opera下无法获取到选取值，在Safari下没问题。
    // debugger;
    if (window.getSelection) {
      const windowSelection = window.getSelection() as any;
      const selectedText = windowSelection.toString();
      if (!selectedText) {
        message.info('请先选中部分词');
        return '';
      }
      if (selectedText.indexOf('<') >= 0 || selectedText.indexOf('>') >= 0) {
        // 屏幕选词存在特殊符号<和>，选词有交集（选词包含关系不能判断）
        console.log('选词**存在交集关系', selectedText);
        message.info('与之前分词重叠，请调整分词方式');
        return '';
      }

      let start = windowSelection.anchorOffset;
      let end = windowSelection.focusOffset;

      if (start > end) {
        // 从后往前取词，需要交换
        [start, end] = [end, start];
      }
      if (end === 0) {
        console.log('选词**不在合法区域内', start, end, selectedText);
        message.info('请先选中部分词');
        return '';
      }
      const tempStr1 = words.substring(0, start);
      const tempStr2 = words.substring(end);

      // 前半部分tempStr1含有<，则用特殊符号<分割，最后一个没有包含>,则判断为存在包含关系
      if (tempStr1.indexOf('<') >= 0) {
        const arr = tempStr1.split('<');
        if (arr[arr.length - 1].indexOf('>') < 0) {
          console.log('选词**存在被包含关系', tempStr1);
          message.info('与之前分词重叠，请调整分词方式');
          return '';
        }
      }
      console.log(start, end, tempStr1, selectedText, tempStr2);

      return tempStr1 + '<' + selectedText + '>' + tempStr2;
    }
    return '';
  }

  /**选中纠正分词 */
  const handleChooseWord = () => {
    const latestNewWords = getSelectText(noUnderstandWords);
    if (!latestNewWords) {
      return;
    }
    // 更新未理解词
    setNoUnderstandWords(latestNewWords);
    console.log('更新扩展问题新词', latestNewWords);
    // 请求发现新词接口
    getNewWordsList(latestNewWords);
  };

  const onSelectChange = (selectedRowKeys: React.Key[]) => {
    console.log('selectedRowKeys changed: ', selectedRowKeys);
    setSelectedRowKeys(selectedRowKeys);
  };

  // 表格行选择
  const rowSelection = {
    selectedRowKeys,
    onChange: onSelectChange,
    getCheckboxProps: (record: NewWordInfo) => ({
      // 同义词，不可编辑
      disabled: record.wordType === '0',
      name: record.wordType,
    }),
  };

  return (
    <>
      <Modal
        forceRender
        className="newwords-model"
        title={<span className="noselect">{modeType === 'study' ? '新词学习' : '新词录入'}</span>}
        width={1000}
        onCancel={() => closeModal()}
        visible={visible}
        destroyOnClose
        maskClosable={false}
        footer={
          <div
            style={{
              textAlign: 'right',
            }}
          >
            <Button onClick={submitForm} type="primary" loading={confirmLoading}>
              确定
            </Button>
            <Button onClick={() => closeModal()} style={{ marginRight: 8 }}>
              取消
            </Button>
          </div>
        }
      >
        <div className="mgr-header">
          <div className="mgr-header-left">
            <div className="selection-words noselect">{extendQuestionName}</div>
            <Button type="primary" onClick={handleAdd} style={{ marginLeft: 15 }}>
              新建
            </Button>
          </div>
          <div className="mgr-header-right">
            <div className="selection-words">{noUnderstandWords}</div>
            <Button type="primary" onClick={debounce(handleChooseWord, 500)}>
              选中纠正分词
            </Button>
          </div>
        </div>
        <Form
          layout="horizontal"
          labelCol={{ span: 4, offset: 0 }}
          form={form}
          initialValues={{
            lists: newWords,
          }}
        >
          <Table
            className="noselect"
            style={{ overflow: 'auto', maxHeight: 400 }}
            loading={tableLoading}
            rowSelection={rowSelection}
            dataSource={newWords}
            bordered
            rowKey="key"
            columns={[
              {
                title: '新词条',
                key: 'word',
                dataIndex: 'word',
                width: 180,
                render: (text, record, index) => <>{text}</>,
              },
              {
                title: '类型',
                key: 'wordType',
                dataIndex: 'wordType',
                width: 80,
                render: (text, record, index) => (
                  <>
                    {text === '0' && '同义词'}
                    {text === '1' && '词组'}
                  </>
                ),
              },
              {
                title: '词类',
                key: 'wordCategory',
                dataIndex: 'wordCategory',
                render: (text, record, index) => (
                  <Form.Item key={index} name={['lists', index, 'wordCategory']} noStyle>
                    <Select placeholder="请选择" style={{ width: '100%' }}>
                      {/* 新词条-词组 */}
                      <Option key="nodata" value="">
                        无
                      </Option>
                      {newWordGroup.length > 0 &&
                        newWordGroup.map((item: string, index) => {
                          return (
                            <Option key={'new_' + index} value={item}>
                              {item}
                            </Option>
                          );
                        })}
                      {wordGroup.length > 0 &&
                        wordGroup.map((item: WordGroupsInfo, index) => {
                          return (
                            <Option key={'groups_' + index} value={item.wordGroupName}>
                              {item.wordGroupName}
                            </Option>
                          );
                        })}
                    </Select>
                  </Form.Item>
                ),
              },
              {
                title: '别名',
                key: 'wordEntrys',
                dataIndex: 'wordEntrys',
                render: (text, record, index) => (
                  <Form.Item
                    key={index}
                    name={['lists', index, 'wordEntrys']}
                    style={{ marginBottom: 0 }}
                  >
                    <Input allowClear />
                  </Form.Item>
                ),
              },
              {
                title: '必选',
                key: 'isRequired',
                dataIndex: 'isRequired',
                width: 80,
                render: (text, record, index) => (
                  <Form.Item
                    key={index}
                    name={['lists', index, 'isRequired']}
                    valuePropName="checked"
                    style={{ marginBottom: 0 }}
                  >
                    <Checkbox />
                  </Form.Item>
                ),
              },
              {
                title: '自动生成专业词',
                key: 'isAddBusinessWord',
                dataIndex: 'isAddBusinessWord',
                width: 140,
                render: (text, record, index) => (
                  <input
                    type="radio"
                    name="businessWordRadio"
                    className="spe-radio"
                    disabled={record.wordType === '1'}
                    onChange={e => {
                      console.log('自动生成专业词-选择', index, e.target.checked);
                      setCheckedRow(index);
                    }}
                  />
                ),
              },
            ]}
            pagination={false}
          />
        </Form>
      </Modal>
    </>
  );
};

export default NewWordsModel;
